package com.pai4j.pgc.controller.community;
import com.pai4j.common.util.JsonUtil;
import com.pai4j.common.util.SpringContextUtil;
import com.pai4j.domain.community.dto.ai.CCLLMChatRequestDTO;
import com.pai4j.pgc.service.aig.CCAgentService;
import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * OnOpen 表示有浏览器链接过来的时候被调用
 * OnClose 表示浏览器发出关闭请求的时候被调用
 * OnMessage 表示浏览器发消息的时候被调用
 * OnError 表示有错误发生，比如网络断开了等等
 */
@Slf4j
@Component
@ServerEndpoint("/ws/aibot/{userId}")
public class AibotSocket {

    /**
     * 以用户的Id作为key，WebSocket为对象保存起来
     */
    private static Map<String, AibotSocket> clients = new ConcurrentHashMap<String, AibotSocket>();

    /**
     * 会话
     */
    private Session session;

    /**
     * 用户ID
     */
    private String userId;

    /**
     * 建立连接
     *
     * @param session
     */
    @OnOpen
    public void onOpen(@PathParam("userId") String userId, Session session) {
        this.userId = userId;
        this.session = session;
        clients.put(userId, this);
        log.info("onOpen success. sessionId:{}, userId:{}", session.getId(), userId);
    }

    @OnError
    public void onError(Session session, Throwable error) {
        log.info("服务端发生了错误, error message:{}", error.getMessage());
    }

    /**
     * 连接关闭
     */
    @OnClose
    public void onClose() {
        this.clients.remove(userId);
        log.info("onClose success}");
    }

    /**
     * 收到客户端的消息
     *
     * @param message 消息
     * @param session 会话
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        try {

            Map msg = JsonUtil.fromJson(message, Map.class);

            if ("heartbeat".equals(msg.get("type").toString())) {
                // 心跳检测
                doSend(userId, "pong");
                return;
            }
            String query = msg.get("content").toString();
            log.info("来自客户端消息：" + message + "客户端的id是：" + session.getId());

            CCLLMChatRequestDTO requestDTO = new CCLLMChatRequestDTO();
            requestDTO.setMessage(query);
            requestDTO.setPathId(28L);
            try {
                SpringContextUtil.getBean(CCAgentService.class).chatByWebSocket(userId, requestDTO);
            } catch (Exception e) {
                doSend(userId, "服务端繁忙，稍后重试～");
            }
        } catch (Exception e) {
            log.info("onMessage error. message:{}", message, e);
        }
    }

    public static boolean isConnected(String userId) {
        Session session = clients.get(userId).session;
        return session != null && session.isOpen();
    }

    public static void doSend(String userId, String message) {
        Session session = clients.get(userId).session;
        synchronized (session) {
            doSendMsg(session, message);
        }
    }

    public static void doSendMsg(Session session, String message) {
        if (session != null && session.isOpen()) {
            try {
                // 同步写
                session.getBasicRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}